package wci.intermediate.icodeimpl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import wci.intermediate.ICodeFactory;
import wci.intermediate.ICodeKey;
import wci.intermediate.ICodeNode;
import wci.intermediate.ICodeNodeType;

/**
 * <h1>ICodeNodeImpl</h1>
 *
 * <p>中间码-分析树-节点实现</p>
 *
 * <p>Copyright (c) 2009 by Ronald Mak</p>
 * <p>For instructional purposes only.  No warranties.</p>
 */
public class ICodeNodeImpl
    extends HashMap<ICodeKey, Object>
    implements ICodeNode
{
	private static final long serialVersionUID = -5542614552917931131L;
	private ICodeNodeType type;             // 类型
    private ICodeNode parent;               // 父节点
    private ArrayList<ICodeNode> children;  // 子节点

    public ICodeNodeImpl(ICodeNodeType type)
    {
        this.type = type;
        this.parent = null;
        this.children = new ArrayList<ICodeNode>();
    }
    public ICodeNodeType getType()
    {
        return type;
    }
    public ICodeNode getParent()
    {
        return parent;
    }
    public ICodeNode addChild(ICodeNode node)
    {
        if (node != null) {
            children.add(node);
            ((ICodeNodeImpl) node).parent = this;
        }

        return node;
    }
    public List<ICodeNode> getChildren()
    {
        return children;
    }
    public void setAttribute(ICodeKey key, Object value)
    {
        put(key, value);
    }
    public Object getAttribute(ICodeKey key)
    {
        return get(key);
    }
    public ICodeNode copy()
    {
        //这儿只是拷贝了属性，内部的子节点指向相同的存储区。
        ICodeNodeImpl copy =
            (ICodeNodeImpl) ICodeFactory.createICodeNode(type);

        Set<Map.Entry<ICodeKey, Object>> attributes = entrySet();
        Iterator<Map.Entry<ICodeKey, Object>> it = attributes.iterator();

        while (it.hasNext()) {
            Map.Entry<ICodeKey, Object> attribute = it.next();
            copy.put(attribute.getKey(), attribute.getValue());
        }

        return copy;
    }

    public String toString()
    {
        return type.toString();
    }
}
